/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.commons.qrcode.core;


import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 二维码生成器
 *
 * @author Leon Huo
 */
public class GspQrCodeGenerator {

    //生成二维码，默认尺寸为200，颜色为黑色
    public byte[] generateQrCode(String content) throws IOException, WriterException {
        return generateQrCode(content, Color.BLACK, 200);
    }

    //生成二维码，自定义颜色，默认尺寸为200
    public byte[] generateQrCode(String content, Color color) throws IOException, WriterException {
        return generateQrCode(content, color, 200);
    }

    //生成二维码，自定义尺寸，默认颜色为黑色
    public byte[] generateQrCode(String content, int size) throws IOException, WriterException {
        return generateQrCode(content, Color.BLACK, size);
    }

    //生成有logo的二维码，默认尺寸为200，颜色为黑色
    public byte[] generateQrCode(String content, byte[] logo) throws IOException, WriterException {
        return generateQrCode(content, Color.BLACK, 200, logo);
    }

    //生成二维码，自定义尺寸、颜色
    public byte[] generateQrCode(String content, Color color, int size) throws WriterException, IOException {
        BitMatrix bitMatrix = generateQrCodeBitImage(content, size);

        //定义二维码颜色
        MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(color.getRGB(), 0xFFFFFFFF);

        BufferedImage matrixImage = MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig);

        //开始画二维码
        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        ImageIO.write(matrixImage, "png", pngOutputStream);

        matrixImage.flush();

        //MatrixToImageWriter.writeToStream(bitMatrix, "PNG", pngOutputStream);
        return pngOutputStream.toByteArray();
    }

    //生成有logo的二维码，自定义尺寸，默认颜色为黑色
    public byte[] generateQrCode(String content, int size, byte[] logo) throws IOException, WriterException {
        return generateQrCode(content, Color.BLACK, size, logo);
    }

    //生成有logo的二维码，自定义颜色，默认尺寸为200
    public byte[] generateQrCode(String content, Color color, byte[] logo) throws IOException, WriterException {
        return generateQrCode(content, color, 200, logo);
    }

    //生成有logo的二维码，自定义尺寸、颜色
    public byte[] generateQrCode(String content, Color color, int size, byte[] logo) throws WriterException, IOException {
        BitMatrix bitMatrix = generateQrCodeBitImage(content, size);

        //设置二维码颜色
        MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(color.getRGB(), 0xFFFFFFFF);

        BufferedImage matrixImage = MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig);

        Graphics2D g2 = matrixImage.createGraphics();

        int matrixWidth = matrixImage.getWidth();
        int matrixHeight = matrixImage.getHeight();

        BufferedImage logoImage = ImageIO.read(new ByteArrayInputStream(logo));

        //绘制logo
        g2.drawImage(logoImage, matrixWidth / 5 * 2, matrixHeight / 5 * 2, matrixWidth / 5, matrixHeight / 5, null);//绘制
        BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setStroke(stroke);// 设置笔画对象
        //指定弧度的圆角矩形
        RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth / 5 * 2, matrixHeight / 5 * 2, matrixWidth / 5, matrixHeight / 5, 20, 20);
        g2.setColor(Color.white);
        g2.draw(round);// 绘制圆弧矩形

        //设置logo 有一道灰色边框
        BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setStroke(stroke2);// 设置笔画对象
        RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth / 5 * 2 + 2, matrixHeight / 5 * 2 + 2, matrixWidth / 5 - 4, matrixHeight / 5 - 4, 20, 20);
        g2.setColor(new Color(128, 128, 128));
        g2.draw(round2);// 绘制圆弧矩形

        g2.dispose();

        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        ImageIO.write(matrixImage, "png", pngOutputStream);
        matrixImage.flush();
        return pngOutputStream.toByteArray();
    }

    //根据内容尺寸生成二维码位图
    private BitMatrix generateQrCodeBitImage(String code, int size) throws WriterException {
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
        Map hints = new HashMap();
        //设置UTF-8， 防止中文乱码
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //设置二维码四周白色区域的大小
        hints.put(EncodeHintType.MARGIN, 0);
        //设置二维码的容错性
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //画二维码，记得调用multiFormatWriter.encode()时最后要带上hints参数，不然上面设置无效
        return multiFormatWriter.encode(code, BarcodeFormat.QR_CODE, size, size, hints);
    }
}


